#include <iostream>

#define T2_4_4 1
using namespace std;
int main()
{
    cout << "hello c++" << endl;

#if T2_4_1
    const int a = 10;
    const int &b = a;
    cout << b << endl;
    //int &c = a; //const int
#elif T2_4_2
    /* 2.27 下列哪些初始化是合法的，说明原因 */
    //int i = -1, &r = 0; //0 是常量，int引用不能引用常量
    int i2 = 3;
    int *const p = &i2; //合法，但是i2没有定义
    const int i = -1, &r = 0; //合法， 常量引用
    const int *const p3 = &i2; //合法，常量指针常量 p3指针 不能改变i2的值
    const int *p1 = &i2;    //合法， 指针指向一个常量
    //const int &const r2; //引用必须初始化
    const int i3 = i, &r2 = i; //合法 常量初始化和常量引用

    /* 2.28说出下列定义的含义，提出不合法的 */
    //int i, *const cp; //不合法，没有初始化常量指针
    //int *p1, *const p2; //不合法，没有初始化常量指针
    //const int ic, &r = ic; //不合法，没有初始化常量指针
    //const int *const p3; //不合法，没有初始化常量指针
    //const int p;//没有初始化常量

#elif T2_4_3
    //顶层const 底层const
    const int v2 = 0;
    int i = 10;
    int v1 = v2; //合法
    int *p1 = &v1, &r1 = v1; //用于声明引用的const才是底层const， r1不是const
    const int *p2 = &v2, *const p3 = &i, &r2 = v2;
    
    //int &r1 = v1;
    r1 = v2; //合法
    //p1 = p2; //非法， p2是底层const， p1不是；
    p2 = p1; //合法，常量是顶层const
    //p1 = p3; //p3有底层const， p1不是
    p2 = p3; //都是底层const,p3的值不会改变，p2本身是可变的，p3指向的值为const， p2指向的也是const，所以是合法的
    //如果p2 指向的不是const， 那就是不合法的

#elif T2_4_4
    /* constexpr 和常量表达式 */
    int null = 0;
    //int *p = null; /* 非法，指针的初始化必须为常量 */
#endif
    return 0;
}
